﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;

namespace ZOIL.Framework.Core
{
    /// <summary>
    /// 
    /// </summary>
    public static class GeometryExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="referencePoint"></param>
        /// <returns></returns>
        public static Point GetClosestPointOnGeometry(this Geometry shape, Point referencePoint)
        {
            if (shape == null)
            {
                throw new ArgumentNullException("shape");
            }

            if (Double.IsNaN(referencePoint.X) || Double.IsInfinity(referencePoint.X))
                referencePoint.X = 0.0;
            if (Double.IsNaN(referencePoint.Y) || Double.IsInfinity(referencePoint.Y))
                referencePoint.Y = 0.0;

            Point outPoint;
            Point tangent;

            var outlinedPathGeometry = shape.GetOutlinedPathGeometry();

            outlinedPathGeometry.GetPointAtFractionLength(0.0, out outPoint, out tangent);

            var minDistance = Point.Subtract(outPoint, referencePoint).Length;
            
            var returnPoint = outPoint;

            for (double i = 0; i < 1.0; i += 0.05)
            {
                outlinedPathGeometry.GetPointAtFractionLength(i, out outPoint, out tangent);
                if (Point.Subtract(outPoint, referencePoint).Length < minDistance)
                {
                    minDistance = Point.Subtract(outPoint, referencePoint).Length;
                    returnPoint = outPoint;
                }
            }
            return returnPoint;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="shape"></param>
        /// <returns></returns>
        public static Point GetCenterPoint(this Geometry shape)
        {
            if (shape == null)
            {
                throw new ArgumentNullException("shape");
            }

            var ellipse = shape as EllipseGeometry;

            if (ellipse != null)
            {
                return ellipse.Center;
            }
            return new Point(shape.Bounds.X + shape.Bounds.Width / 2.0, shape.Bounds.Y + shape.Bounds.Height / 2.0);
        }

    }
}
